package com.example.service.impl;

import com.example.filter.TokenFilter;
import com.example.mapper.TeacherFirstPageMapper;
import com.example.mapper.TeacherSecondPageMapper;
import com.example.pojo.*;
import com.example.pojo.Class;
import com.example.service.TeacherFirstPageService;
import com.example.utils.PasswordSecurity;
import com.example.utils.ThreadLocalA;
import com.opencsv.CSVReader;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Slf4j
@Service
public class TeacherFirstPageImpl implements TeacherFirstPageService {

    @Autowired
    private TeacherFirstPageMapper teacherFirstPageMapper;

    /**
     * 修改老师个人信息
     */
    @Override
    public LoginMsg updateInfo(Teacher teacher) {
        try {
            //1.查询老师信息
            Teacher requireTeacher =teacherFirstPageMapper.select(teacher.getUsername());
            //2.判断旧密码是否正确
            if(!("".equals(teacher.getOldPassword())) &&PasswordSecurity.checkPassword(teacher.getOldPassword(), requireTeacher.getPassword())){
                //旧密码正确,将新密码加密后更新数据库
                teacher.setNewPassword(PasswordSecurity.hashPassword(teacher.getNewPassword()));
                //1.修改数据库老师信息
                teacherFirstPageMapper.updateInfo(teacher);
                //2.查询修改后的老师信息返回
                LoginMsg loginMsg = teacherFirstPageMapper.selectUpdated(teacher);
                if (loginMsg != null) {
                    loginMsg.setRole(2);
                }
                return loginMsg;
            }else if("".equals(teacher.getNewPassword())){
                teacherFirstPageMapper.updateInfo(teacher);
                //2.查询修改后的老师信息返回
                LoginMsg loginMsg = teacherFirstPageMapper.selectUpdated(teacher);
                if (loginMsg != null) {
                    loginMsg.setRole(2);
                }
                return loginMsg;
            }else {
                LoginMsg loginMsg = new LoginMsg();
                loginMsg.setMsg("原密码错误");
                return loginMsg;
            }

        } catch (Exception e) {
            log.error("修改失败,请检查是否填写错误" + e.getMessage());
            StringBuilder msg = new StringBuilder(e.getMessage());
            if (msg.toString().contains("Duplicate entry") && msg.toString().contains("for key 'teachers.username'")) {
                msg.setLength(0);
                msg.append("该用户名已存在");
            } else if (msg.toString().contains("Duplicate entry") && msg.toString().contains("for key 'teachers.email'")) {
                msg.setLength(0);
                msg.append("该邮箱已存在,请检查是否填写错误");
            } else if (msg.toString().contains("too long") && msg.toString().contains("'username'")) {
                msg.setLength(0);
                msg.append("用户名长度不能超过20个字符");
            } else if (msg.toString().contains("too long") && msg.toString().contains("'name'")) {
                msg.setLength(0);
                msg.append("姓名长度不能超过20个字符");
            } else if (msg.toString().contains("too long") && msg.toString().contains("'password'")) {
                msg.setLength(0);
                msg.append("密码长度太长");
            } else {
                msg.setLength(0);
                msg.append("修改失败,请检查是否填写错误");
            }
            LoginMsg loginMsg = new LoginMsg();
            loginMsg.setMsg(msg.toString());
            return loginMsg;
        }
    }

    /**
     * 查询老师所教授的班级
     */
    @Override
    public List<String> searchClass(Integer teacherId) {
        List<String> list = new ArrayList<>();
        List<Class> classList = teacherFirstPageMapper.searchClass(teacherId);
        classList.forEach(class1 -> {
            String className = class1.getClassName() ;
            list.add(className);
        });
        return list;
    }

    /**
     * 查询老师所教授的班级的科目
     */
    @Override
    public List<String> searchSubject(Integer teacherId, String className) {
        List<String> subjectList = teacherFirstPageMapper.searchSubject(teacherId, className);
        return subjectList;
    }

    /**
     * 查询老师所教授的班级的科目的学期
     */
    @Override
    public List<String> searchSemester(Integer teacherId, String className, String subjectName) {
        List<String> semesterList = teacherFirstPageMapper.searchSemester(teacherId, className, subjectName);
        return semesterList;
    }

    /**
     * 录入单科成绩
     */
    @Override
    public Result insertSingleScore(Score score) {

        try {
            if (teacherFirstPageMapper.isExistStudent(score)) {
                if (!teacherFirstPageMapper.isExistScore(score)) {
                    BigDecimal min = BigDecimal.ZERO;
                    BigDecimal max = new BigDecimal("100");
                    if (score.getUsualScore()  == null || score.getMidtermScore() == null || score.getFinalScore() == null || score.getUsualScore().compareTo(min) <0 || score.getUsualScore().compareTo(max) > 0||  score.getMidtermScore().compareTo(min) < 0 || score.getMidtermScore().compareTo(max) > 0|| score.getFinalScore().compareTo(min) < 0 || score.getFinalScore().compareTo(max) > 0) {
                        return Result.fail("请输入正确成绩（0-100）!");
                    } else if (score.getSubjectName() == null || "".equals(score.getSubjectName())) {
                        return Result.fail("请选择科目名称!");
                    }
                    Percentage percentage= teacherFirstPageMapper.inqueryPercentage(score);
                    //计算综合分数
                    String percentageUsualScore = percentage.getPercentageUsualScore().replaceAll("%", "");
                    String percentageMidtermScore = percentage.getPercentageMidtermScore().replaceAll("%", "");
                    String percentageFinalScore = percentage.getPercentageFinalScore().replaceAll("%", "");
                    //计算综合分数
                    score.setScore((score.getUsualScore().multiply(new BigDecimal(percentageUsualScore)).divide(new BigDecimal(100))).add(score.getMidtermScore().multiply(new BigDecimal(percentageMidtermScore)).divide(new BigDecimal(100))).add(score.getFinalScore().multiply(new BigDecimal(percentageFinalScore)).divide(new BigDecimal(100))));

                    if (score.getScore().compareTo(new BigDecimal(60)) >= 0) {
                        Integer credit = teacherFirstPageMapper.inqueryCredit(score);
                        score.setEarnCredit(credit);
                    } else {
                        score.setEarnCredit(0);
                    }
                    teacherFirstPageMapper.insertSingleScore(score);
                    return Result.success("录入成功!");
                } else {
                    return Result.fail("该学生已录入该科目成绩!");
                }
            } else if (score.getStudentId() == null) {
                return Result.fail("请输入正确的学号!");
            } else {
                return Result.fail("该学生不存在!");
            }
        } catch (Exception e) {
            log.error("插入单科成绩失败" + e.getMessage());
            if (e.getMessage().contains("For input string: \"\""))
                return Result.fail("请输入信息");

            return Result.fail(e.getMessage());
        }
    }

    /**
     * 批量导入成绩
     */
    @Transactional(rollbackFor = {Exception.class})//添加事务管理
    @Override
    public ResponseEntity<String> batchInputScore(MultipartFile file) {
        if (file.isEmpty()) {
            return ResponseEntity.badRequest().body("上传文件不能为空");
        }
        //判断文件大小
        if (file.getSize() > 1024 * 1024 * 10) {
            return ResponseEntity.badRequest().body("上传文件大小不能超过10MB");
        }

        String contentType = file.getContentType();
        if (!Arrays.asList(
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                "text/csv").contains(contentType)) {
            return ResponseEntity.badRequest().body("仅支持xlsx/csv格式文件");
        }

        List<Score> scoreList = new ArrayList<>();
        int scoreCount = 0;//记录导入的行数

        try {
            // 使用try-with-resources确保所有流关闭
            if (contentType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) {
                try (InputStream is = file.getInputStream();
                     Workbook workbook = new XSSFWorkbook(is)) {
                    log.info("开始解析Excel文件");
                    Sheet sheet = workbook.getSheetAt(0);
                    Iterator<Row> rowIterator = sheet.iterator();

                    // 跳过标题行
                    if (rowIterator.hasNext()) rowIterator.next();

                    while (rowIterator.hasNext()) {
                        Row row = rowIterator.next();
                        Score score = parseExcelRow(row);
                        scoreCount++;
                        if(!teacherFirstPageMapper.isExistScore(score)) {
                            scoreList.add(score);
                        }
                    }
                }
            } else if (contentType.equals("text/csv")) {
                try (InputStream is = file.getInputStream();
                     InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
                     CSVReader reader = new CSVReader(isr)) {

                    // 使用迭代器避免加载全部数据到内存
                    Iterator<String[]> rowIterator = reader.iterator();
                    int currentRow = 0;

                    // 跳过标题行
                    if (rowIterator.hasNext()) {
                        rowIterator.next();
                        currentRow++;
                    }

                    while (rowIterator.hasNext()) {
                        String[] cells = rowIterator.next();
                        currentRow++;
                        try {
                            Score score = parseCsvRow(cells, currentRow);
                            scoreCount++;
                            if(!teacherFirstPageMapper.isExistScore(score)) {
                                scoreList.add(score);
                            }
                        } catch (IllegalArgumentException e) {
                            throw new IllegalArgumentException("第" + currentRow + "行数据错误：" + e.getMessage());
                        }
                    }
                }
            }
            log.info("成功解析" + scoreList.size() + "条数据");

            // 批量插入数据
            if(!scoreList.isEmpty()) {
                teacherFirstPageMapper.batchInsertScores(scoreList);
            }
            if(scoreCount!=0&&scoreCount!=scoreList.size()) {
                return ResponseEntity.ok("成功导入" + scoreList.size() + "条数据,部分学生成绩已存在");
            }
            return ResponseEntity.ok("成功导入" + scoreList.size() + "条数据");
        } catch (NumberFormatException e) {

            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//回滚事务

            return ResponseEntity.badRequest().body("数字格式错误：" + e.getMessage());
        } catch (IllegalArgumentException e) {

            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//回滚事务

            return ResponseEntity.badRequest().body(e.getMessage());
        } catch (Exception e) {

            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//回滚事务

            if(e.getMessage().contains("'subject_id' cannot be null")){
                return ResponseEntity.badRequest().body("部分科目信息错误,科目不存在");
            }
            log.error("文件处理失败：", e);
            return ResponseEntity.internalServerError()
                    .body("文件处理失败：" + e.getClass().getSimpleName());
        }
    }

    // Excel解析
    private Score parseExcelRow(Row row) {
        int rowNum = row.getRowNum() + 1; // 实际行号
        Score score = new Score();

        try {
            //获取线程本地变量
            String username = ThreadLocalA.get();
            score.setTeacherId(teacherFirstPageMapper.inqueryTeacherId(username));

            // 学号（强制数字类型）
            Cell studentIdCell = row.getCell(0, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
            if (studentIdCell == null) {
                throw new IllegalArgumentException("第" + rowNum + "行学号不能为空");
            }
            score.setStudentId((int) studentIdCell.getNumericCellValue());




            // 科目名称（强制字符串类型）
            Cell subjectNameCell = row.getCell(2, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
            if (subjectNameCell == null) {
                throw new IllegalArgumentException("第" + rowNum + "行科目名称不能为空");
            }
            score.setSubjectName(getCellStringValue(row.getCell(2)));

            // 班级名字
            score.setClassName(getCellStringValue(row.getCell(1)));
            if(!teacherFirstPageMapper.isExistManageClass(score)){
                throw new IllegalArgumentException("第" + rowNum + "行无权限管理该班级");
            }

/*            // 学期
            Cell semesterCell = row.getCell(3, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
            if (semesterCell == null) {
                throw new IllegalArgumentException("第" + rowNum + "行学期不能为空");
            }
            score.setSemester(getCellStringValue(semesterCell));*/

            // 平时成绩校验（0-100）
            Cell usualScoreCell = row.getCell(3);
            if(usualScoreCell == null){
                throw new IllegalArgumentException("第" + rowNum + "行平时成绩为空");
            }else{
                String numericValue = new DataFormatter().formatCellValue(usualScoreCell).trim();
                try {
                    BigDecimal scoreValue = new BigDecimal(numericValue);
                    if (scoreValue.compareTo(BigDecimal.ZERO) < 0 ||
                            scoreValue.compareTo(new BigDecimal("100")) > 0) {


                        throw new IllegalArgumentException("第" + rowNum + "行平时成绩超出范围");
                    }
                    score.setUsualScore(scoreValue);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("第" + rowNum + "行平时成绩格式错误");
                }
            }
            //期中成绩
            Cell midtermScoreCell = row.getCell(4);
            if(midtermScoreCell== null){
                throw new IllegalArgumentException("第" + rowNum + "行期中成绩为空");
            }else{
                String numericValue = new DataFormatter().formatCellValue(midtermScoreCell).trim();
                try {
                    BigDecimal scoreValue = new BigDecimal(numericValue);
                    if (scoreValue.compareTo(BigDecimal.ZERO) < 0 ||
                            scoreValue.compareTo(new BigDecimal("100")) > 0) {
                        throw new IllegalArgumentException("第" + rowNum + "行期中成绩超出范围");
                    }
                    score.setMidtermScore(scoreValue);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("第" + rowNum + "行期中成绩格式错误");
                }
            }
            //期末成绩
            Cell finalScoreCell = row.getCell(5);
            if(finalScoreCell == null){
                throw new IllegalArgumentException("第" + rowNum + "行期末成绩为空");
            }else{
                String numericValue = new DataFormatter().formatCellValue(finalScoreCell).trim();
                try {
                    BigDecimal scoreValue = new BigDecimal(numericValue);
                    if (scoreValue.compareTo(BigDecimal.ZERO) < 0 ||
                            scoreValue.compareTo(new BigDecimal("100")) > 0) {
                        throw new IllegalArgumentException("第" + rowNum + "行期末成绩超出范围");
                    }
                    score.setFinalScore(scoreValue);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("第" + rowNum + "行期末成绩格式错误");
                }
            }


            //综合成绩
            Percentage percentage= teacherFirstPageMapper.inqueryPercentage(score);
            //计算综合分数
            String percentageUsualScore = percentage.getPercentageUsualScore().replaceAll("%", "");
            String percentageMidtermScore = percentage.getPercentageMidtermScore().replaceAll("%", "");
            String percentageFinalScore = percentage.getPercentageFinalScore().replaceAll("%", "");
            //计算综合分数
            score.setScore((score.getUsualScore().multiply(new BigDecimal(percentageUsualScore)).divide(new BigDecimal(100))).add(score.getMidtermScore().multiply(new BigDecimal(percentageMidtermScore)).divide(new BigDecimal(100))).add(score.getFinalScore().multiply(new BigDecimal(percentageFinalScore)).divide(new BigDecimal(100))));

            if (score.getScore().compareTo(new BigDecimal(60)) >= 0) {
                Integer credit = teacherFirstPageMapper.inqueryCredit(score);
                score.setEarnCredit(credit);
            } else {
                score.setEarnCredit(0);
            }

            if(!teacherFirstPageMapper.isExistStudent(score)){
                throw new IllegalArgumentException("第" + rowNum + "行学生不存在");
            }

        } catch (IllegalStateException e) {
            throw new IllegalArgumentException("第" + rowNum + "行数据类型错误：" + e.getMessage());
        }
        return score;
    }

    // CSV解析
    private Score parseCsvRow(String[] cells, int currentRow) {
        Score score = new Score();
        try {
            //获取线程本地变量
            String username = ThreadLocalA.get();
            score.setTeacherId(teacherFirstPageMapper.inqueryTeacherId(username));
            // 学号
            if (cells[0].trim().isEmpty()) {
                throw new IllegalArgumentException("第" + currentRow +"行学号不能为空");
            }
            score.setStudentId(Integer.parseInt(cells[0].trim()));


            // 科目名称
            if(!cells[2].trim().isEmpty()){
                throw new IllegalArgumentException("第" + currentRow +"行科目不能为空");
            }
            score.setSubjectName(cells[2].trim());

            // 班级名字
            if (!cells[1].trim().isEmpty()) {
                String className = cells[1].trim();
                score.setClassName(className);
            }else{
                throw new IllegalArgumentException("第" + currentRow +"行班级不能为空");
            }
            if(!teacherFirstPageMapper.isExistManageClass(score)){
                throw new IllegalArgumentException("第" + currentRow + "行无权限管理该班级");
            }
   /*         // 学期
            if (cells[3].trim().isEmpty()) {
                throw new IllegalArgumentException("第" + currentRow +"行学期不能为空");
            }
            score.setSemester(cells[3].trim());*/

            // 平时成绩
            String scoreStr = cells[3].trim();
            if(scoreStr.isEmpty()){
                throw new IllegalArgumentException("第" + currentRow +"行平时成绩为空");
            }
            BigDecimal scoreValue = new BigDecimal(scoreStr);
            if (scoreValue.compareTo(BigDecimal.ZERO) < 0 ||
                    scoreValue.compareTo(new BigDecimal("100")) > 0) {
                throw new IllegalArgumentException("成绩超出范围（0-100）");
            }
            score.setUsualScore(scoreValue);

            // 期中成绩
            String scoreStr1 = cells[4].trim();
            if(scoreStr1.isEmpty()){
                throw new IllegalArgumentException("第" + currentRow +"行期中成绩为空");
            }
            BigDecimal scoreValue1 = new BigDecimal(scoreStr1);
            if (scoreValue1.compareTo(BigDecimal.ZERO) < 0 ||
                    scoreValue1.compareTo(new BigDecimal("100")) > 0) {
                throw new IllegalArgumentException("成绩超出范围（0-100）");
            }
            score.setMidtermScore(scoreValue1);

            // 期末成绩
            String scoreStr2 = cells[5].trim();
            if(scoreStr2.isEmpty()){
                throw new IllegalArgumentException("第" + currentRow +"行平时成绩为空");
            }
            BigDecimal scoreValue2 = new BigDecimal(scoreStr2);
            if (scoreValue2.compareTo(BigDecimal.ZERO) < 0 ||
                    scoreValue2.compareTo(new BigDecimal("100")) > 0) {
                throw new IllegalArgumentException("成绩超出范围（0-100）");
            }
            score.setFinalScore(scoreValue2);

            //综合成绩
            Percentage percentage= teacherFirstPageMapper.inqueryPercentage(score);
            //计算综合分数
            String percentageUsualScore = percentage.getPercentageUsualScore().replaceAll("%", "");
            String percentageMidtermScore = percentage.getPercentageMidtermScore().replaceAll("%", "");
            String percentageFinalScore = percentage.getPercentageFinalScore().replaceAll("%", "");
            //计算综合分数
            score.setScore((score.getUsualScore().multiply(new BigDecimal(percentageUsualScore)).divide(new BigDecimal(100))).add(score.getMidtermScore().multiply(new BigDecimal(percentageMidtermScore)).divide(new BigDecimal(100))).add(score.getFinalScore().multiply(new BigDecimal(percentageFinalScore)).divide(new BigDecimal(100))));

            if (score.getScore().compareTo(new BigDecimal(60)) >= 0) {
                Integer credit = teacherFirstPageMapper.inqueryCredit(score);
                score.setEarnCredit(credit);
            } else {
                score.setEarnCredit(0);
            }

            if(!teacherFirstPageMapper.isExistStudent(score)){
                throw new IllegalArgumentException("第" + currentRow + "行学生不存在");
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("第" + currentRow + "行数字格式错误：" + e.getMessage());
        }
        return score;
    }

    // 获取单元格字符串值（去除首尾空格）
    private String getCellStringValue(Cell cell) {
        if (cell == null) return "";

        DataFormatter formatter = new DataFormatter();
        return formatter.formatCellValue(cell).trim();
    }

}

